#ifndef RBT_ENCODING_INCLUDE
#define RBT_ENCODING_INCLUDE

#include "Text.h"

RETURNCODE E_ENCODING_BUFFESIZE = -14001;
RETURNCODE E_ENCODING_MTOW      = -14002;
RETURNCODE E_ENCODING_WTOM      = -14003;
RETURNCODE E_ENCODING_ALLOC_BUFFER = -14004;
RETURNCODE E_ENCODING_ALLOC_STRING = -14005;
RETURNCODE E_ENCODING_PREMABLE_SIZE= -14006;

enum EncodingType
{
	ENCODING_UNKNOW  = -1,
	/*Default = 0,*/
	/*Ansi    = 1,*/
	ENCODING_UNICODE   = 2,
	ENCODING_UNICODE_BIGEND,
	ENCODING_GB2312,
	ENCODING_UTF32,
	ENCODING_UTF32_BIGEND,
	ENCODING_UTF7,
	ENCODING_UTF8
};

class Encoding
{
public:
	enum EncodingCodePage
	{
		CODE_PAGE_DEFAULT        = 0,
		CODE_PAGE_UNICODE        = 1200,
		CODE_PAGE_UNICODE_BIGEND = 12001,
		CODE_PAGE_GB2312         = 20963,

		CODE_PAGE_UTF32          = 12000,
		CODE_PAGE_UFT32_BIGEND   = 12001,

		CODE_PAGE_UTF7           = 65000,
		CODE_PAGE_UTF8           = 65001
	};
protected:

	const static int32 DEFAULT_CODE_PAGE = 0;
	const static int32 DEFAULT_CHAR_SIZE = sizeof(tchar);

	virtual int32 GetMaxCharSize( cuint32& byteSize , uint32& charSize );
	virtual int32 GetMaxByteSize( cuint32& charSize , uint32 byteSize );

public:
	virtual int32 GetString( cbyte* bytes , cuint32 byteSize , string& value );
	virtual int32 GetBytes( cstring& value , byte* bytes , cuint32 byteSize );
	virtual int32 GetCodePage( EncodingCodePage& codePage ) = 0;

	virtual int32 GetCharSize( uint32& charSize ) = 0;
	virtual int32 GetByteSize( uint32& byteSize ) = 0;
	virtual int32 GetPerambleSize( uint32& perambleSize ) = 0;
	virtual int32 GetPeramble( byte* bytes , cuint32& byteSize ) = 0;
	virtual int32 Decode( cbyte*  bytes , uint32 byteSize ,  tchar* chars , uint32 charSize , uint32& useCharSize , uint32& useByteSize ) = 0;
	virtual int32 Encode( ctchar* chars , uint32 charSize ,  byte* bytes , uint32 byteSize , uint32& useCharSize , uint32& useByteSize ) = 0;

	static Encoding* Create( EncodingType encodings );
	static void      Destroy(Encoding* encoding );


};

class DBCSEncoding :
	public Encoding
{
	EncodingCodePage m_codePage;
public:
	DBCSEncoding( EncodingCodePage codePage );

	virtual int32 GetCharSize( uint32& charSize );
	virtual int32 GetByteSize( uint32& byteSize );
	virtual int32 Decode( cbyte* bytes , uint32 byteSize , tchar* chars , uint32 charSize , uint32& useCharSize , uint32& useByteSize );
	virtual int32 Encode( ctchar* chars , uint32 charSize ,  byte* bytes , uint32 byteSize , uint32& useCharSize , uint32& useByteSize );
	virtual int32 GetCodePage( EncodingCodePage& codePage );
	virtual int32 GetPerambleSize( uint32& perambleSize );
	virtual int32 GetPeramble( byte* bytes , cuint32& byteSize );
};



class UnicodeEncoding :
	public Encoding
{
	bool m_peramble;
public:
	UnicodeEncoding( bool permable = true );
	virtual int32 GetCharSize( uint32& charSize );
	virtual int32 GetByteSize( uint32& byteSize );
	virtual int32 Decode( cbyte* bytes , uint32 byteSize , tchar* chars , uint32 charSize , uint32& useCharSize , uint32& useByteSize );
	virtual int32 Encode( ctchar* chars , uint32 charSize ,  byte* bytes , uint32 byteSize , uint32& useCharSize , uint32& useByteSize );
	virtual int32 GetCodePage( EncodingCodePage& codePage );
	virtual int32 GetPerambleSize( uint32& perambleSize );
	virtual int32 GetPeramble( byte* bytes , cuint32& byteSize );
};

class UTF8Encoding :
	public Encoding
{
	bool m_preamble;
public:
	UTF8Encoding(bool preamble = true );
	virtual int32 GetCharSize( uint32& charSize );
	virtual int32 GetByteSize( uint32& byteSize );
	virtual int32 Decode( cbyte* bytes , uint32 byteSize , tchar* chars , uint32 charSize , uint32& useCharSize , uint32& useByteSize );
	virtual int32 Encode( ctchar* chars , uint32 charSize ,  byte* bytes , uint32 byteSize , uint32& useCharSize , uint32& useByteSize );
	virtual int32 GetCodePage( EncodingCodePage& codePage );
	virtual int32 GetPerambleSize( uint32& perambleSize );
	virtual int32 GetPeramble( byte* bytes , cuint32& byteSize );
};

#endif